//
//  SCoreData.m
//  STool
//
//  Created by banggo on 15/7/13.
//
//

#import "SCoreData.h"
#import <objc/runtime.h>
#import "SDefine.h"

#define scLOG 1
#if scLOG
#define SCDLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
#define SCDLog(fmt, ...)
#endif
@implementation SCoreData
{
    NSString *saveDbName;
}


@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            // Replace this implementation with code to handle the error appropriately.
            // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            SCDLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

#pragma mark - Core Data stack

// Returns the managed object context for the application.
// If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
- (NSManagedObjectContext *)managedObjectContext
{
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] init];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return _managedObjectContext;
}

// Returns the managed object model for the application.
// If the model doesn't already exist, it is created from the application's model.
- (NSManagedObjectModel *)managedObjectModel
{
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:self.databaseName withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    
    return _managedObjectModel;
}

// Returns the persistent store coordinator for the application.
// If the coordinator doesn't already exist, it is created and the application's store added to it.
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:[NSString stringWithFormat:@"%@.sqlite",self.databaseName]];
    /**
     samuel add
     防止更新表格闪退
     */
    NSMutableDictionary *options = [[NSMutableDictionary alloc] init];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
    @try {
        NSError *error = nil;
        _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
        if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
            SCDLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    return _persistentStoreCoordinator;
}
#pragma mark - Application's Documents directory

// Returns the URL to the application's Documents directory.获取Documents路径
- (NSURL *)applicationDocumentsDirectory
{
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

#pragma mark - Others

- (void)dictionaryToEntity:(NSDictionary *)dict entity:(NSObject*)entity
{
    if (dict && entity) {
        for (NSString *keyName in [dict allKeys]) {
            SEL coreDataSetValue = NSSelectorFromString(@"setValue:forKey:");
            if ([entity respondsToSelector:coreDataSetValue]) {
                [entity performSelector:coreDataSetValue withObject:[NSString stringWithFormat:@"%@",[dict objectForKey:keyName]] withObject:keyName];
            }
        }
    }
}
+(id)getObjectWithClassName:(NSString *)aClassName {
    id rtnObject = nil;
    Class myClazz = NSClassFromString(aClassName);
    if (myClazz) {
        rtnObject = [[myClazz alloc] init];
    }
    return rtnObject;
}
#pragma mark - －－－－－－－－－Core封装
#pragma mark - 单例
+ (id)sharedInstance
{
    static dispatch_once_t pred;
    static SCoreData *sharedInstance = nil;
    dispatch_once(&pred, ^{
        sharedInstance = [[SCoreData alloc] init];
        sharedInstance.timeRecord = 0;
    });
    return sharedInstance;
}
#pragma mark - 初始化（表名，数据库名）
- (instancetype)setTableName:(NSString *)tableName andDatabaseName:(NSString*)databaseName;
{
    if (![databaseName isEqualToString:self.databaseName]) {
        _managedObjectContext = nil;
        _managedObjectModel = nil;
        _persistentStoreCoordinator = nil;
    }
    if (!tableName && self.tableName) {
    }
    else
    {
        self.tableName = tableName;
    }
    if (!databaseName && self.databaseName) {
        return self;
    }
    self.databaseName = databaseName;
    return self;
}
/**
 *  插入数据
 *
 *  @param dictionary 需要插入的字典数据
 *  @param key        需要检查的参数(nil即为无检查参数)
 *
 *  @return 是否成功
 */
#pragma mark - 插入数据
- (BOOL)insertCoreData:(NSDictionary*)dictionary andKey:(NSString*)key,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        return NO;
    }
    self.timeRecord = ___getTimestamp;
    
    NSMutableArray *getAllKey = [NSMutableArray array];
    if (key) {
        [getAllKey addObject:key];
    }
    va_list arguments;
    va_start(arguments, key);
    NSString *getKey;
    if(key)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllKey addObject:getKey];
            }
        }
    }
    va_end(arguments);
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    /**
     *  查询数据（如果有相同的数据便不插入）
     */
    if ([getAllKey count]<1) {
        return NO;
    }
    NSString *predicateString = [NSString stringWithFormat:@"%@ = '%@'",[getAllKey objectAtIndex:0],[dictionary objectForKey:[getAllKey objectAtIndex:0]]];
    for (int i = 1 ;i<[getAllKey count];i++) {
        predicateString = [NSString stringWithFormat:@"%@ AND %@ = '%@'",predicateString,[getAllKey objectAtIndex:i],[dictionary objectForKey:[getAllKey objectAtIndex:i]]];
    }
    fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateString];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSError *error;
    NSArray *fetchedObjects;
    @try {
        fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
        /**
         *  判断key相同
         */
        if ([fetchedObjects count]>0) {
            SCDLog(@"插入失败，拥有相同数据[%@]\n时间[%f]s",[error localizedDescription],___getTimestamp - self.timeRecord);
            return NO;
        }
        NSManagedObject *inseobject =  [NSEntityDescription insertNewObjectForEntityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
        [self dictionaryToEntity:dictionary entity:inseobject];
        
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    /**
     *  插入数据
     */
    NSError *error2;
    if(![[self managedObjectContext] save:&error2])
    {
        SCDLog(@"插入失败[%@]\n时间[%f]s",[error2 localizedDescription],___getTimestamp - self.timeRecord);
        return NO;
    }
    SCDLog(@"插入成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return YES;
    
    
}

/**
 *  遍历查询
 *
 *  @param pageSize    查多少条
 *  @param currentPage 从第几条开始查
 *
 *  @return 返回数据
 */
#pragma mark - 遍历查询（全部，带分页）
- (NSMutableArray*)selectData:(int)pageSize
                    andOffset:(int)currentPage
             andCompositorKey:(NSString*)compostinStr;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    /**
     拼接条件
     */
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    if (compostinStr) {
        /**
         *  排序
         */
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:compostinStr ascending:NO];
        fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
    }
    //    [fetchRequest setFetchBatchSize:currentPage*pageSize];
    [fetchRequest setFetchLimit:pageSize];
    [fetchRequest setFetchOffset:currentPage];
    
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects;
    NSError *error;
    @try {
        fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    if ([fetchedObjects count]<1) {
        SCDLog(@"查询失败[%@]\n时间[%f]s",[error localizedDescription],___getTimestamp - self.timeRecord);
        return nil;
    }
    NSMutableArray *resultArray = [NSMutableArray array];
    for (NSManagedObject *getObjects in fetchedObjects) {
        [resultArray addObject:getObjects];
    }
    SCDLog(@"查询成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return resultArray;
}

#pragma mark - 遍历查询（分页）
- (NSMutableArray*)selectDataWithPageSize:(int)pageSize
                           andCurrentPage:(int)currentPage
                         andCompositorKey:(NSString*)compostinStr
                           andKeyAndValue:(id)ids,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    NSMutableArray *getAllObject = [NSMutableArray array];
    va_list arguments;
    va_start(arguments, ids);
    NSString *getKey;
    if(ids)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllObject addObject:getKey];
            }
        }
    }
    va_end(arguments);
    [getAllObject insertObject:ids atIndex:0];
    
    if ([getAllObject count]<2) {
        return nil;
    }
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setFetchBatchSize:currentPage*pageSize];
    [fetchRequest setFetchLimit:pageSize];
    [fetchRequest setFetchOffset:currentPage *pageSize];
    return [self selectDataWithChooseType:fetchRequest andKVArray:getAllObject andCompositorKey:compostinStr];
}
#pragma mark - 遍历查询（偏移量）
- (NSMutableArray*)selectDataWithPageSize:(int)pageSize
                               andOffsets:(int)offset
                         andCompositorKey:(NSString*)compostinStr
                           andKeyAndValue:(id)ids,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    NSMutableArray *getAllObject = [NSMutableArray array];
    va_list arguments;
    va_start(arguments, ids);
    NSString *getKey;
    if(ids)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllObject addObject:getKey];
            }
        }
    }
    va_end(arguments);
    [getAllObject insertObject:ids atIndex:0];
    
    if ([getAllObject count]<2) {
        return nil;
    }
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setFetchLimit:pageSize];
    [fetchRequest setFetchOffset:offset];
    return [self selectDataWithChooseType:fetchRequest andKVArray:getAllObject andCompositorKey:compostinStr];
}
- (NSMutableArray*)selectDataWithChooseType:(NSFetchRequest*)fetchRequest
                                 andKVArray:(NSMutableArray*)kvArray
                           andCompositorKey:(NSString*)compostinStr;
{
    
    /**
     *  查询语句
     */
    NSString *predicateString = [NSString stringWithFormat:@"%@ = '%@'",[kvArray objectAtIndex:0],[kvArray objectAtIndex:1]];
    for (int i = 2 ;i<[kvArray count];) {
        predicateString = [NSString stringWithFormat:@"%@ AND %@ = '%@'",predicateString,[kvArray objectAtIndex:i],[kvArray objectAtIndex:i+1]];
        i = i+2;
    }
    if (compostinStr) {
        /**
         *  排序
         */
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:compostinStr ascending:NO];
        fetchRequest.sortDescriptors = [NSArray arrayWithObject:sort];
    }
    fetchRequest.predicate = [NSPredicate predicateWithFormat:predicateString];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    [fetchRequest setEntity:entity];
    NSError *error;
    NSArray *fetchedObjects;
    @try {
        fetchedObjects = [[self managedObjectContext] executeFetchRequest:fetchRequest error:&error];
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    
    if ([fetchedObjects count]<1) {
        SCDLog(@"查询失败[%@]\n时间[%f]s",[error localizedDescription],___getTimestamp - self.timeRecord);
        return nil;
    }
    NSMutableArray *resultArray = [NSMutableArray array];
    for (NSManagedObject *getObjects in fetchedObjects) {
        [resultArray addObject:getObjects];
    }
    SCDLog(@"查询成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return resultArray;
    
}
#pragma mark - 删除
-(BOOL)deleteDataWithKeyAndValue:(id)ids,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    NSMutableArray *getAllObject = [NSMutableArray array];
    va_list arguments;
    va_start(arguments, ids);
    NSString *getKey;
    if(ids)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllObject addObject:getKey];
            }
        }
    }
    va_end(arguments);
    [getAllObject insertObject:ids atIndex:0];
    
    if ([getAllObject count]<=1) {
        return nil;
    }
    NSManagedObjectContext *context = [self managedObjectContext];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSError *error = nil;
    NSArray *datas = [self selectDataWithChooseType:request andKVArray:getAllObject andCompositorKey:nil];
    if (!error && datas && [datas count])
    {
        for (NSManagedObject *obj in datas)
        {
            [context deleteObject:obj];
        }
        if (![context save:&error])
        {
            SCDLog(@"删除失败[%@]\n时间[%f]s",[error localizedDescription],___getTimestamp - self.timeRecord);
            return NO;
        }
    }
    SCDLog(@"删除成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return YES;
}
#pragma mark - 更新数据（单一条件更新，对象字典）
- (BOOL)upDataMainKey:(NSString*)mainKey
            mainValue:(NSString*)mainValue
  andUpDataDictionary:(NSMutableDictionary*)dictionary;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    NSString *predicateString = [NSString stringWithFormat:@"%@ = '%@'",mainKey,mainValue];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.predicate = [NSPredicate predicateWithFormat:predicateString];
    [request setEntity:entity];
    NSError *error = nil;
    NSArray *datas;
    @try {
        datas = [[self managedObjectContext] executeFetchRequest:request error:&error];
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    if (!error && datas && [datas count])
    {
        for(int i =0;i < [datas count];i++)
        {
            NSManagedObject *gets = [datas objectAtIndex:i];
            [self dictionaryToEntity:dictionary entity:gets];
        }
        if (![[self managedObjectContext] save:&error]) {
            //更新成功
            SCDLog(@"更新失败[%@]\n时间[%f]s",error,___getTimestamp - self.timeRecord);
            return NO;
        }
    }
    SCDLog(@"更新成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return YES;
    
}

#pragma mark - 更新数据（单一条件更新，对象输入键值对）
- (BOOL)upDataMainKey:(NSString*)mainKey
            mainValue:(NSString*)mainValue
 andUpDataKeyAndValue:(id)ids,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    NSMutableArray *getAllObject = [NSMutableArray array];
    va_list arguments;
    va_start(arguments, ids);
    NSString *getKey;
    if(ids)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllObject addObject:getKey];
            }
        }
    }
    va_end(arguments);
    [getAllObject insertObject:ids atIndex:0];
    NSMutableDictionary *newDic = [NSMutableDictionary dictionary];
    for (int i = 0 ;i<[getAllObject count];) {
        [newDic setObject:[getAllObject objectAtIndex:i+1] forKey:[getAllObject objectAtIndex:i]];
        i = i+2;
    }
    
    NSString *predicateString = [NSString stringWithFormat:@"%@ = '%@'",mainKey,mainValue];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.predicate = [NSPredicate predicateWithFormat:predicateString];
    [request setEntity:entity];
    NSError *error = nil;
    NSArray *datas;
    @try {
        datas = [[self managedObjectContext] executeFetchRequest:request error:&error];
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    if (!error && datas && [datas count])
    {
        for(int i =0;i < [datas count];i++)
        {
            NSManagedObject *gets = [datas objectAtIndex:i];
            [self dictionaryToEntity:newDic entity:gets];
        }
        if (![[self managedObjectContext] save:&error]) {
            SCDLog(@"更新失败[%@]\n时间[%f]s",error,___getTimestamp - self.timeRecord);
            return NO;
        }
    }
    SCDLog(@"更新成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return YES;
}
#pragma mark - 更新数据（多条件更新，对象输入键值对）
- (BOOL)upDataDictionary:(NSMutableDictionary*)dictionary
    andUpDataKeyAndValue:(id)ids,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        return nil;
    }
    self.timeRecord = ___getTimestamp;
    
    NSMutableArray *getAllObject = [NSMutableArray array];
    va_list arguments;
    va_start(arguments, ids);
    NSString *getKey;
    if(ids)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllObject addObject:getKey];
            }
        }
    }
    va_end(arguments);
    [getAllObject insertObject:ids atIndex:0];
    /**
     *  检索条件
     */
    NSString *predicateString = [NSString stringWithFormat:@"%@ = '%@'",[getAllObject objectAtIndex:0],[getAllObject objectAtIndex:1]];
    for (int i = 2 ;i<[getAllObject count];) {
        predicateString = [NSString stringWithFormat:@"%@ AND %@ = '%@'",predicateString,[getAllObject objectAtIndex:i],[getAllObject objectAtIndex:i+1]];
        i = i+2;
    }
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.predicate = [NSPredicate predicateWithFormat:predicateString];
    [request setEntity:entity];
    NSError *error = nil;
    NSArray *datas;
    @try {
        datas = [[self managedObjectContext] executeFetchRequest:request error:&error];
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    if (!error && datas && [datas count])
    {
        for(int i =0;i < [datas count];i++)
        {
            NSManagedObject *gets = [datas objectAtIndex:i];
            [self dictionaryToEntity:dictionary entity:gets];
        }
        if (![[self managedObjectContext] save:&error]) {
            SCDLog(@"更新失败[%@]\n时间[%f]s",error,___getTimestamp - self.timeRecord);
            return NO;
        }
    }
    SCDLog(@"更新成功－时间[%f]s",___getTimestamp - self.timeRecord);
    return YES;
}
#pragma mark - 获取数据库长度
- (NSUInteger)getDataCount;
{
    if (!self.databaseName || !self.tableName) {
        return 0;
    }
    self.timeRecord = ___getTimestamp;
    
    NSString *predicateString = [NSString stringWithFormat:@"COUNT(*)"];
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.predicate = [NSPredicate predicateWithFormat:predicateString];
    [request setEntity:entity];
    NSError *error = nil;
    NSArray *datas;
    @try {
        datas = [[self managedObjectContext] executeFetchRequest:request error:&error];
    }
    @catch (NSException *exception) {
        ;
    }
    @finally {
        ;
    }
    if (!error && datas && [datas count])
    {
        return [[datas objectAtIndex:0]integerValue];
    }
    return 0;
}
- (void)upDataDictionary:(NSMutableDictionary*)dictionary
                   block:(void(^)(id rDictionary))processResult
               failblock:(void(^)(NSError *error))failResult
    andUpDataKeyAndValue:(id)ids,...NS_REQUIRES_NIL_TERMINATION;
{
    if (!self.databaseName || !self.tableName) {
        failResult(nil);
    }
    self.timeRecord = ___getTimestamp;
    
    NSMutableArray *getAllObject = [NSMutableArray array];
    va_list arguments;
    va_start(arguments, ids);
    NSString *getKey;
    if(ids)
    {
        while((getKey = va_arg(arguments,NSString *)))
        {
            if (getKey) {
                [getAllObject addObject:getKey];
            }
        }
    }
    va_end(arguments);
    [getAllObject insertObject:ids atIndex:0];
    /**
     *  检索条件
     */
    NSString *predicateString = [NSString stringWithFormat:@"%@ = '%@'",[getAllObject objectAtIndex:0],[getAllObject objectAtIndex:1]];
    for (int i = 2 ;i<[getAllObject count];) {
        predicateString = [NSString stringWithFormat:@"%@ AND %@ = '%@'",predicateString,[getAllObject objectAtIndex:i],[getAllObject objectAtIndex:i+1]];
        i = i+2;
    }
    NSEntityDescription *entity = [NSEntityDescription entityForName:self.tableName inManagedObjectContext:[self managedObjectContext]];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    request.predicate = [NSPredicate predicateWithFormat:predicateString];
    [request setEntity:entity];
    ___WEAKSELF
    __weak NSFetchRequest *weak_request = request;
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(concurrentQueue, ^{
        __block NSArray *resultArray = nil;
        __block NSError *error = nil;
        dispatch_sync(concurrentQueue, ^{
            resultArray = [[NSMutableArray alloc]init];
            @try {
                resultArray = [[weakSelf managedObjectContext] executeFetchRequest:weak_request error:&error];
            }
            @catch (NSException *exception) {
                ;
            }
            @finally {
                ;
            }
            if (!error && resultArray && [resultArray count])
            {
                for(int i =0;i < [resultArray count];i++)
                {
                    NSManagedObject *gets = [resultArray objectAtIndex:i];
                    [weakSelf dictionaryToEntity:dictionary entity:gets];
                }
                if (![[weakSelf managedObjectContext] save:&error]) {
                    SCDLog(@"更新失败[%@]\n时间[%f]s",error,___getTimestamp - weakSelf.timeRecord);
                    resultArray = nil;
                }
            }
            SCDLog(@"更新成功－时间[%f]s",___getTimestamp - weakSelf.timeRecord);
        });
        dispatch_sync(dispatch_get_main_queue(), ^{
            if(resultArray == nil || resultArray.count<1)
            {
                failResult(error);
                return;
            }
            processResult(resultArray);
        });
    });
    
    
}
@end
